using System;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Security.Permissions;
using System.Web.UI.Design;
using System.Text;
using System.Collections.Generic;

namespace Heckel.EasyTools.Diagramming
{
    public enum CallBackType
    {
        NodeBeingRepositioned = 0,
        NodeDoubleClicked = 1,
        CheckingNodeStatuses = 2,
        NodeDetailsClicked = 3,
        NodeDeleted = 4,
        Undefined = 6
    }

    public enum ExecutingEvent
    {
        [StringValue("StatusElapsed")]
        StatusElapsed = 0,
        [StringValue("DoubleClicked")]
        DoubleClicked = 1,
        [StringValue("Repositioned")]
        Repositioned = 2,
        [StringValue("DetailsClicked")]
        DetailsClicked = 3,
        [StringValue("DeleteClicked")]
        DeleteClicked = 4
    }

    public delegate void NodeCheckStatusEventHandler(object o, NodeStatusEventArgs e);
    public delegate void NodeRepositionedEventHandler(object o, NodeRepositionEventArgs e);
    public delegate void NodeDoubleClickedEventHandler(object o, NodeDetailsEventArgs e);
    public delegate void NodeDetailsClickedEventHandler(object o, NodeDetailsEventArgs e);
    public delegate void NodeDeleteClickedEventHandler(object o, NodeDetailsEventArgs e);

    [
    ToolboxData("<{0}:DiagramContainer runat=server></{0}:DiagramContainer>"), 
    Designer(typeof(Heckel.EasyTools.Diagramming.DiagramDesigner))
    ]
    public class DiagramContainer : CompositeControl, ICallbackEventHandler
    {
        private NodeStatusEventArgs checkNodeStatus;

        [Category("Action"), Description("Raised when the status timer associated with NodeStatusCheckInterval elapses")]
        public event NodeCheckStatusEventHandler NodeStatusElapsed
        {
            add { Events.AddHandler(StringEnum.GetStringValue(ExecutingEvent.StatusElapsed), value); }
            remove { Events.RemoveHandler(StringEnum.GetStringValue(ExecutingEvent.StatusElapsed), value); }
        }

        [Category("Action"), Description("Raised when a node is repositioned")]
        public event NodeRepositionedEventHandler NodeRepositioned
        {
            add { Events.AddHandler(StringEnum.GetStringValue(ExecutingEvent.Repositioned), value); }
            remove { Events.RemoveHandler(StringEnum.GetStringValue(ExecutingEvent.Repositioned), value); }
        }

        [Category("Action"), Description("Raised when a node is double clicked")]
        public event NodeDoubleClickedEventHandler NodeDoubleClicked
        {
            add { Events.AddHandler(StringEnum.GetStringValue(ExecutingEvent.DoubleClicked), value); }
            remove { Events.RemoveHandler(StringEnum.GetStringValue(ExecutingEvent.DoubleClicked), value); }
        }

        [Category("Action"), Description("Raised when a node's detail button is clicked")]
        public event NodeDetailsClickedEventHandler NodeDetailsClicked
        {
            add { Events.AddHandler(StringEnum.GetStringValue(ExecutingEvent.DetailsClicked), value); }
            remove { Events.RemoveHandler(StringEnum.GetStringValue(ExecutingEvent.DetailsClicked), value); }
        }

        [Category("Action"), Description("Raised when a node is deleted")]
        public event NodeDeleteClickedEventHandler NodeDeleted
        {
            add { Events.AddHandler(StringEnum.GetStringValue(ExecutingEvent.DeleteClicked), value); }
            remove { Events.RemoveHandler(StringEnum.GetStringValue(ExecutingEvent.DeleteClicked), value); }
        }

        public void RaiseNodeEvent(ExecutingEvent eventType, EventArgs e)
        {
            if (Events[StringEnum.GetStringValue(eventType)] != null)
            {
                switch (eventType)
                {
                    case ExecutingEvent.Repositioned:
                        //save changes to viewstate
                        int nodeIndex = ReturnNodeIndexByUniqueIdentifier(((NodeRepositionEventArgs)e).NodeUniqueIdentifier);
                        AllNodes[nodeIndex].XPos = ((NodeRepositionEventArgs)e).X;
                        AllNodes[nodeIndex].YPos = ((NodeRepositionEventArgs)e).Y;

                        //callback
                        ((NodeRepositionedEventHandler)Events[StringEnum.GetStringValue(ExecutingEvent.Repositioned)])(this, (NodeRepositionEventArgs)e);
                        break;
                    case ExecutingEvent.DetailsClicked:
                        ((NodeDetailsClickedEventHandler)Events[StringEnum.GetStringValue(ExecutingEvent.DetailsClicked)])(this, (NodeDetailsEventArgs)e);
                        break;
                    case ExecutingEvent.DoubleClicked:
                        ((NodeDoubleClickedEventHandler)Events[StringEnum.GetStringValue(ExecutingEvent.DoubleClicked)])(this, (NodeDetailsEventArgs)e);
                        break;
                    case ExecutingEvent.StatusElapsed:
                        ((NodeCheckStatusEventHandler)Events[StringEnum.GetStringValue(ExecutingEvent.StatusElapsed)])(this, (NodeStatusEventArgs)e);
                        break;
                    case ExecutingEvent.DeleteClicked:
                        ((NodeDeleteClickedEventHandler)Events[StringEnum.GetStringValue(ExecutingEvent.DeleteClicked)])(this, (NodeDetailsEventArgs)e);
                        break;
                }
            }
        }

        public virtual int NodeStatusCheckInterval
        {
            get { if (ViewState["_nodeStatusCheckInterval"] != null) { return (int)ViewState["_nodeStatusCheckInterval"]; } else { return -1; } }
            set { ViewState["_nodeStatusCheckInterval"] = value; }
        }

        public virtual int ZIndex
        {
            get { if (ViewState["_zIndex"] != null) { return (int)ViewState["_zIndex"]; } else { ViewState["_zIndex"] = 0;  return 0; } }
            set { ViewState["_zIndex"] = value; }
        }

        public virtual CallBackType LastCallbackType
        {
            get
            {
                if (ViewState["_lastCallBackType"] == null)
                    return CallBackType.Undefined;
                else
                    return (CallBackType)ViewState["_lastCallBackType"];
            }
            set { ViewState["_lastCallBackType"] = value; }
        }

        public virtual bool AllowBodyDragging
        {
            get
            {
                if (ViewState["_allowBodyDragging"] == null)
                    return true;
                else
                    return (bool)ViewState["_allowBodyDragging"];
            }
            set { ViewState["_allowBodyDragging"] = value; }
        }

        public virtual string OnWarningCssClass
        {
            get
            {
                if (ViewState["_onWarningCssClass"] != null)
                    return ViewState["_onWarningCssClass"].ToString();
                else
                    return "";
            }
            set
            {
                ViewState["_onWarningCssClass"] = value;
            }
        }

        public virtual string OnErrorCssClass
        {
            get
            {
                if (ViewState["_onErrorCssClass"] != null)
                    return ViewState["_onErrorCssClass"].ToString();
                else
                    return "";
            }
            set
            {
                ViewState["_onErrorCssClass"] = value;
            }
        }

        public virtual string OnInfoCssClass
        {
            get
            {
                if (ViewState["_onInfoCssClass"] != null)
                    return ViewState["_onInfoCssClass"].ToString();
                else
                    return "";
            }
            set
            {
                ViewState["_onInfoCssClass"] = value;
            }
        }

        public virtual List<DiagramNode> AllNodes
        {
            get
            {
                if (ViewState["AllNodes"] == null)
                    ViewState["AllNodes"] = new List<DiagramNode>();

                return (List<DiagramNode>)ViewState["AllNodes"];
            }
            set
            {
                ViewState["AllNodes"] = value;
            }
        }

        public int ReturnNodeIndexByUniqueIdentifier(int id)
        {
            int tNodes = -1;
            foreach (DiagramNode dn in AllNodes)
            {
                tNodes++;
                if (dn.DependencyID.Equals(id))
                    return tNodes;
            }

            return -1;
        }

        public DiagramContainer()
        {

        }

        /*
        private string navURL()
        {
            string[] splitPath = Page.Request.ServerVariables["PATH_INFO"].ToString().Split('/');
            string rbPath = "";
            //for (int px = 0; px < splitPath.Length - 1; px++)
            //    rbPath += splitPath[px] + " ";

            //rbPath = rbPath.Trim().Replace(" ", "/");

            string navURL = "http://" + Page.Request.ServerVariables["SERVER_NAME"].ToString() + ":" + Page.Request.ServerVariables["SERVER_PORT"].ToString(); // +"/" + rbPath;

            return navURL;
        }
        */

        private void CreateDiagrammingJavascript()
        {
            //create returnImageFunction -- dependency from the diagramming.js file
            StringBuilder returnImage = new StringBuilder();
            returnImage.Append("function returnImage(nbr, dir) { " + Environment.NewLine);
            returnImage.Append("var rImage = '';" + Environment.NewLine);
            returnImage.Append("switch (nbr) { " + Environment.NewLine);

            for (int i = 1; i < 257; i++)
            {
                if (i == 1 || i == 2 || i == 4 || i == 8 || i == 16 || i == 32 || i == 64 || i == 128 || i == 256)
                {
                    returnImage.Append("case " + i.ToString() + ": " + Environment.NewLine);
                    returnImage.Append("if (dir == 'up') { " + Environment.NewLine);
                    returnImage.Append("rImage = '" + Page.ClientScript.GetWebResourceUrl(typeof(InternalDiagramNode), "Heckel.EasyTools.Diagramming.Resources.draw" + i.ToString() + "up.gif") + "'; " + Environment.NewLine);
                    returnImage.Append("} else { " + Environment.NewLine);
                    returnImage.Append("rImage = '" + Page.ClientScript.GetWebResourceUrl(typeof(InternalDiagramNode), "Heckel.EasyTools.Diagramming.Resources.draw" + i.ToString() + "down.gif") + "'; " + Environment.NewLine);
                    returnImage.Append("}" + Environment.NewLine);
                    returnImage.Append("break; " + Environment.NewLine);
                }
            }

            returnImage.Append("}" + Environment.NewLine);
            returnImage.Append("return rImage;" + Environment.NewLine);
            returnImage.Append("} " + Environment.NewLine);

            StringBuilder returnArrow = new StringBuilder();
            returnArrow.Append("function returnArrow(type) { " + Environment.NewLine);
            returnArrow.Append("var rArrow = '';" + Environment.NewLine);
            returnArrow.Append("switch (type) { " + Environment.NewLine);
            returnArrow.Append("case 'down': rArrow = '" + Page.ClientScript.GetWebResourceUrl(typeof(InternalDiagramNode), "Heckel.EasyTools.Diagramming.Resources.redArrowDown.gif") + "'; break; " + Environment.NewLine);
            returnArrow.Append("case 'up': rArrow = '" + Page.ClientScript.GetWebResourceUrl(typeof(InternalDiagramNode), "Heckel.EasyTools.Diagramming.Resources.redArrowUp.gif") + "'; break; " + Environment.NewLine);
            returnArrow.Append("}" + Environment.NewLine);
            returnArrow.Append("return rArrow;" + Environment.NewLine);
            returnArrow.Append("}" + Environment.NewLine);

            if (!Page.ClientScript.IsClientScriptIncludeRegistered("diagramming"))
                Page.ClientScript.RegisterClientScriptInclude("diagramming", Page.ClientScript.GetWebResourceUrl(typeof(InternalDiagramNode), "Heckel.EasyTools.Diagramming.Resources.diagramming.js"));

            if (!Page.ClientScript.IsClientScriptBlockRegistered("diagrammingImageBuilding"))
                Page.ClientScript.RegisterClientScriptBlock(typeof(InternalDiagramNode), "diagrammingImageBuilding", returnImage.ToString(), true);

            if (!Page.ClientScript.IsClientScriptBlockRegistered("diagrammingArrowBuilding"))
                Page.ClientScript.RegisterClientScriptBlock(typeof(InternalDiagramNode), "diagrammingArrowBuilding", returnArrow.ToString(), true);
        }

        protected override void CreateChildControls()
        {
            if (!this.DesignMode)
            {
                //load serialized nodes from viewstate
                foreach (DiagramNode node in AllNodes)
                {
                    InternalDiagramNode newDiagram = new InternalDiagramNode(node.ImageUrl, node.DependencyName, node.DependencyDescription, node.DependencyClientID, node.DependencyID, node.XPos, node.YPos, node.ParentOf, node.ChildOf);
                    newDiagram.Width = node.Width;
                    newDiagram.Height = node.Height;
                    newDiagram.BackColor = node.BackColor;
                    newDiagram.ForeColor = node.ForeColor;
                    newDiagram.BorderColor = node.BorderColor;
                    newDiagram.DetailsButtonText = node.DetailsButtonText;
                    newDiagram.DeleteNodeCssClass = node.DeleteNodeCssClass;
                    Controls.Add(newDiagram);
                }

                //list images to preload
                LiteralControl lc = new LiteralControl();
                StringBuilder imagesToLoad = new StringBuilder();
                imagesToLoad.Append("<div id=\"preload\" style=\"height:0;overflow:hidden\">");

                for (int i = 1; i < 257; i++)
                {
                    if (i == 1 || i == 2 || i == 4 || i == 8 || i == 16 || i == 32 || i == 64 || i == 128 || i == 256)
                    {
                        imagesToLoad.Append("<img alt = '' src = '" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.draw" + i.ToString() + "up.gif") + "'/>");
                        imagesToLoad.Append("<img alt = '' src = '" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.draw" + i.ToString() + "down.gif") + "'/>");
                    }
                }

                imagesToLoad.Append("<img alt = '' src = '" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.redArrowUp.gif") + "'/>");
                imagesToLoad.Append("<img alt = '' src = '" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.redArrowDown.gif") + "'/>");

                Controls.Add(new LiteralControl(imagesToLoad.ToString()));

                //modal css
                string modalCss = "<link rel=\"stylesheet\" href=\"" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.modalbox.css") + "\" type=\"text/css\" media=\"screen\" />";
                Controls.Add(new LiteralControl(modalCss));

                //dynamic css class needed for modal
                StringBuilder modalLoading = new StringBuilder();
                modalLoading.Append("<style type=\"text/css\"> #MB_loading { padding: 1.5em; text-indent: -10000px; background: transparent url(" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.spinner.gif") + ") 50% 0 no-repeat;</style>");
                Controls.Add(new LiteralControl(modalLoading.ToString()));

                //tooltip css
                string tooltipCss = "<link rel=\"stylesheet\" href=\"" + Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.tooltips.css") + "\" type=\"text/css\" media=\"screen\" />";
                Controls.Add(new LiteralControl(tooltipCss));
            }
        }

        /*
        public virtual DiagramNode FindNodeByClientId(string id)
        {
            foreach (Control dn in this.Controls)
                if (dn is DiagramNode)
                    if (((DiagramNode)dn).NodeID.Equals(id))
                        return (DiagramNode)dn;

            return null;
        }
         * */

        protected override void OnPreRender(EventArgs e)
        {
            //initial script (for drawing initial lines and initializing timer if needed);
            StringBuilder bodyDragging = new StringBuilder();

            StringBuilder loadFunction = new StringBuilder();
            if (!Page.ClientScript.IsStartupScriptRegistered("initLoadScript"))
            {
                //previous was in the init tag
                CreateDiagrammingJavascript();

                //preload the images
                StringBuilder preLoader = new StringBuilder();
                preLoader.Append("preloadedImages = document.getElementById('preload').getElementsByTagName('img'); ");
                Page.ClientScript.RegisterStartupScript(typeof(DiagramContainer), "preloadingImages", preLoader.ToString(), true);

                //global preloadedImages
                Page.ClientScript.RegisterClientScriptBlock(typeof(DiagramContainer), "globalPreloadedImages", "var preloadedImages;", true);

                //drag drop functionality
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "dragdrop", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.dom-drag.js"));
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "callbackevents", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.callbackevents.js"));

                //modal dialogue functionality
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "prototype", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.prototype.js"));
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "scriptaculous", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.scriptaculous.js?load=builder,effects"));
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "effects", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.effects.js"));
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "builder", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.builder.js"));
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "modalbox", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.modalbox.js"));

                //tooltips functionality
                Page.ClientScript.RegisterClientScriptInclude(typeof(DiagramContainer), "tooltips", Page.ClientScript.GetWebResourceUrl(typeof(DiagramContainer), "Heckel.EasyTools.Diagramming.Resources.tooltips.js"));

                if (AllowBodyDragging)
                {
                    bodyDragging.Append("var isBodyDragging = false; " +
                                        "var initX = 0; " +
                                        "var initY = 0; " +
                                        "var dragX = 0; " +
                                        "var dragY = 0; " +
                                        "var bDrag = 0; " + Environment.NewLine);

                    bodyDragging.Append("document.onmousedown = function(e) " +
                                        "{ " +
                                        "    isBodyDragging = true; " +
                                        "    if (!e) var e = window.event; " +
                                        "    if (e.pageX || e.pageY) " +
                                        "    { " +
                                        "        initX = e.pageX; " +
                                        "        initY = e.pageY; " +
                                        "    } " +
                                        "    else if (e.clientX || e.clientY) " +
                                        "    { " +
                                        "        initX = e.clientX; " +
                                        "        initY = e.clientY; " +
                                        "    } " +
                                        "    //window.status = 'set init: ' + initX + ',' + initY; return true;" +
                                        "} " + Environment.NewLine);


                    bodyDragging.Append("document.onmouseup = function(e) { isBodyDragging = false; " + Environment.NewLine);

                    bodyDragging.Append("document.onmousemove = function(e) " +
                                         "{ " +
                                         "if (isBodyDragging) " +
                                         "{ " +
                                         "bDrag++; " +
                                         "if (bDrag % 5 == 0) { " +
                                         "if (!e) var e = window.event; " +
                                         "if (e.pageX || e.pageY) " +
                                         " { " +
                                         "  dragX = e.pageX; " +
                                         "  dragY = e.pageY; " +
                                         "} " +
                                         "else if (e.clientX || e.clientY) " +
                                         "{ " +
                                         "  dragX = e.clientX; " +
                                         "  dragY = e.clientY; " +
                                         "} " +
                                         " //window.status = \"x: \" + (dragX - initX) + \", y:\" + (dragY - initY); ");
                }

                if (NodeStatusCheckInterval != -1)
                    loadFunction.Append("setInterval(\"" + Page.ClientScript.GetCallbackEventReference(this, "'" + ((int)CallBackType.CheckingNodeStatuses).ToString() + "'", "ReturnNodeStatuses", "null") + "\", " + NodeStatusCheckInterval + "); ");

                foreach (Control dn in this.Controls)
                {
                    if (dn is InternalDiagramNode)
                    {
                        string _parentOfIds = "";
                        foreach (string dependentNode in ((InternalDiagramNode)dn).ParentOfIds)
                            _parentOfIds += dependentNode + " ";
                        _parentOfIds = _parentOfIds.Trim().Replace(" ", ",");

                        string _childOfIds = "";
                        foreach (string dependentNode in ((InternalDiagramNode)dn).ChildOfIds)
                            _childOfIds += dependentNode + " ";
                        _childOfIds = _childOfIds.Trim().Replace(" ", ",");

                        loadFunction.Append("if (document.getElementById('" + ((InternalDiagramNode)dn).NodeID + "')) { drawParentLine('" + ((InternalDiagramNode)dn).NodeID + "','" + _parentOfIds + "', " + ((InternalDiagramNode)dn).XPos + "," + ((InternalDiagramNode)dn).YPos + "); drawChildLine('" + ((InternalDiagramNode)dn).NodeID + "', '" + _childOfIds + "', " + ((InternalDiagramNode)dn).XPos + "," + ((InternalDiagramNode)dn).YPos + "); } ");

                        if (AllowBodyDragging)
                        {
                            bodyDragging.Append("MoveNode('" + ((InternalDiagramNode)dn).NodeID + "', '" + _parentOfIds + "','" + _childOfIds + "', (dragX - initX), (dragY - initY)); " + Environment.NewLine);
                            bodyDragging.Append("drawParentLine('" + ((InternalDiagramNode)dn).NodeID + "','" + _parentOfIds + "', " + ((InternalDiagramNode)dn).XPos + "," + ((InternalDiagramNode)dn).YPos + "); drawChildLine('" + ((InternalDiagramNode)dn).NodeID + "', '" + _childOfIds + "', " + ((InternalDiagramNode)dn).XPos + "," + ((InternalDiagramNode)dn).YPos + "); " + Environment.NewLine);
                        }
                    }
                }

                if (AllowBodyDragging)
                {
                    bodyDragging.Append("} } " +
                                        "return true; " +
                                        "} " + Environment.NewLine);

                    Page.ClientScript.RegisterClientScriptBlock(typeof(DiagramContainer), "initDragScript", bodyDragging.ToString(), true);
                }

                //return css class name
                StringBuilder returnClassName = new StringBuilder();
                returnClassName.Append("function returnClassName(logType) { ");
                returnClassName.Append("switch(logType) { ");
                returnClassName.Append("case 'warning': ");
                returnClassName.Append("return '" + OnWarningCssClass + "'; ");
                returnClassName.Append("case 'info': ");
                returnClassName.Append("return '" + OnInfoCssClass + "'; ");
                returnClassName.Append("case 'error': ");
                returnClassName.Append("return '" + OnErrorCssClass + "'; ");
                returnClassName.Append("} ");
                returnClassName.Append("} ");
                Page.ClientScript.RegisterClientScriptBlock(typeof(DiagramContainer), "returnClassName", returnClassName.ToString(), true);

                //register load script
                Page.ClientScript.RegisterStartupScript(typeof(DiagramContainer), "initLoadScript", loadFunction.ToString(), true);
            }

            base.OnPreRender(e);
        }

        public void RaiseCallbackEvent(String eventArgument)
        {
            string callbackString = eventArgument.Substring(1, eventArgument.Length - 1);
            switch (Convert.ToInt32(eventArgument.Substring(0, 1)))
            {
                case (int)CallBackType.CheckingNodeStatuses:
                    LastCallbackType = CallBackType.CheckingNodeStatuses;

                    Dictionary<int, string> getIds = new Dictionary<int, string>();

                    foreach (Control cl in this.Controls)
                        if (cl is InternalDiagramNode)
                            getIds.Add(((InternalDiagramNode)cl).NodeUniqueIdentifier, ((InternalDiagramNode)cl).NodeID);

                    checkNodeStatus = new NodeStatusEventArgs(getIds);

                    string eName = StringEnum.GetStringValue(ExecutingEvent.StatusElapsed);
                    if (Events[eName] != null)
                        RaiseNodeEvent(ExecutingEvent.StatusElapsed, checkNodeStatus);

                    break;
            }
        }

        public string GetCallbackResult()
        {
            switch (LastCallbackType)
            {
                case CallBackType.CheckingNodeStatuses:

                    string clientScript = "";

                    if (checkNodeStatus.HasErrors)
                        foreach (KeyValuePair<string, string> allErrors in checkNodeStatus.Errors)
                            clientScript += allErrors.Key.ToString() + "~e~|" + allErrors.Value.ToString() + "@";

                    if (checkNodeStatus.HasWarnings)
                        foreach (KeyValuePair<string, string> allWarnings in checkNodeStatus.Warnings)
                            clientScript += allWarnings.Key.ToString() + "~w~|" + allWarnings.Value.ToString() + "@";

                    if (checkNodeStatus.HasInfo)
                        foreach (KeyValuePair<string, string> allInfo in checkNodeStatus.Info)
                            clientScript += allInfo.Key.ToString() + "~i~|" + allInfo.Value.ToString() + "@";

                    if (clientScript != "")
                        clientScript = clientScript.Substring(0, clientScript.Length - 1);

                    string allIds = "";
                    foreach (string s in checkNodeStatus.AllIds.Values)
                        allIds += s.ToString() + " ";
                    allIds = allIds.Trim().Replace(" ", "|");

                    return allIds + "##" + clientScript;

                default:
                    return "";
            }
        }
    }
}
